package com.zte.cl.utils;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;

import org.apache.log4j.Logger;

public class DateUtil {
	private static final Logger loggerService = Logger.getLogger(DateUtil.class);

	public static final String C_DATE_DIVISION = "-";

	public static final String C_TIME_PATTON_DEFAULT = "yyyy-MM-dd HH:mm:ss";
	public static final String C_DATE_PATTON_DEFAULT = "yyyy-MM-dd";
	public static final String C_DATETIME_PATION_DEFAULT = "yyyy-MM-dd HH:mm";
	public static final String C_DATA_PATTON_YYYYMMDD = "yyyyMMdd";
	public static final String C_TIME_PATTON_HHMMSS = "HH:mm:ss";
	public static final String C_DATE_PATTON_YYYYMMDDHHMMSS = "yyyyMMddHHmmss";

	public static final int C_ONE_SECOND = 1000;
	public static final int C_ONE_MINUTE = 60 * C_ONE_SECOND;
	public static final int C_ONE_HOUR = 60 * C_ONE_MINUTE;
	public static final long C_ONE_DAY = 24 * C_ONE_HOUR;

	/**
	 * Return the current date
	 * 
	 * @return － DATE<br>
	 */
	public static Date getCurrentDate() {
		Calendar cal = Calendar.getInstance();
		Date currDate = cal.getTime();
		return currDate;
	}

	/**
	 * 将20090510102050转成Date类型 对应日期2009-05-10 10:20:50
	 * 
	 * @param dateStr
	 * @return
	 */
	public static Date parseBossDate(String dateStr) {
		SimpleDateFormat formate = new SimpleDateFormat(DateUtil.C_DATE_PATTON_YYYYMMDDHHMMSS);
		try {
			return formate.parse(dateStr);
		} catch (ParseException e) {
			loggerService.error("", e);
			return null;
		}
	}

	/**
	 * Return the current date string
	 * 
	 * @return － 产生的日期字符串<br>
	 */
	public static String getCurrentDateStr() {
		Calendar cal = Calendar.getInstance();
		Date currDate = cal.getTime();

		return format(currDate);
	}

	/**
	 * Return the current date in the specified format
	 * 
	 * @param strFormat
	 * @return
	 */
	public static String getCurrentDateStr(String strFormat) {
		Calendar cal = Calendar.getInstance();
		Date currDate = cal.getTime();

		return format(currDate, strFormat);
	}

	/**
	 * Parse a string and return a date value
	 * 
	 * @param dateValue
	 * @return
	 * @throws Exception
	 */
	public static Date parseDate(String dateValue) {
		return parseDate(C_DATE_PATTON_DEFAULT, dateValue);
	}

	/**
	 * Parse a strign and return a datetime value
	 * 
	 * @param dateValue
	 * @return
	 */
	public static Date parseDateTime(String dateValue) {
		return parseDate(C_TIME_PATTON_DEFAULT, dateValue);
	}

	public static Date parseTime(String dateValue) {
		return parseTime(C_DATETIME_PATION_DEFAULT, dateValue);
	}

	/**
	 * Parse a string and return the date value in the specified format
	 * 
	 * @param strFormat
	 * @param dateValue
	 * @return
	 * @throws ParseException
	 * @throws Exception
	 */
	public static Date parseDate(String strFormat, String dateValue) {
		if (dateValue == null || "".equals(dateValue))
			return null;

		SimpleDateFormat dateFormat = null;

		if (strFormat == null) {
			strFormat = C_TIME_PATTON_DEFAULT;
			dateFormat = new SimpleDateFormat(strFormat);
		} else if (strFormat.indexOf("EEE") == -1) {
			dateFormat = new SimpleDateFormat(strFormat);
		} else if (strFormat.indexOf("星期") > -1)
			dateFormat = new SimpleDateFormat(strFormat, Locale.CHINESE);
		else {
			dateFormat = new SimpleDateFormat(strFormat, Locale.ENGLISH);
		}

		Date newDate = null;

		try {
			newDate = dateFormat.parse(dateValue);
		} catch (ParseException pe) {
			loggerService.error("", pe);
			newDate = null;
		}

		return newDate;
	}

	/**
	 * 将Timestamp类型的日期转换为系统参数定义的格式的字符串。
	 * 
	 * @param aTs_Datetime
	 *            需要转换的日期。
	 * @return 转换后符合给定格式的日期字符串
	 */
	public static String format(Date aTs_Datetime) {
		return format(aTs_Datetime, C_DATE_PATTON_DEFAULT);
	}

	/**
	 * 将Timestamp类型的日期转换为系统参数定义的格式的字符串。
	 * 
	 * @param aTs_Datetime
	 *            需要转换的日期。
	 * @return 转换后符合给定格式的日期字符串
	 */
	public static String formatTime(Date aTs_Datetime) {
		return format(aTs_Datetime, C_TIME_PATTON_DEFAULT);
	}

	/**
	 * 将Date类型的日期转换为系统参数定义的格式的字符串。
	 * 
	 * @param aTs_Datetime
	 * @param as_Pattern
	 * @return
	 */
	public static String format(Date aTs_Datetime, String as_Pattern) {
		if (aTs_Datetime == null || as_Pattern == null)
			return null;

		SimpleDateFormat dateFromat = new SimpleDateFormat();
		dateFromat.applyPattern(as_Pattern);

		return dateFromat.format(aTs_Datetime);
	}

	/**
	 * @param aTs_Datetime
	 * @param as_Format
	 * @return
	 */
	public static String formatTime(Date aTs_Datetime, String as_Format) {
		if (aTs_Datetime == null || as_Format == null)
			return null;

		SimpleDateFormat dateFromat = new SimpleDateFormat();
		dateFromat.applyPattern(as_Format);

		return dateFromat.format(aTs_Datetime);
	}

	public static String getFormatTime(Date dateTime) {
		return formatTime(dateTime, C_TIME_PATTON_HHMMSS);
	}

	/**
	 * @param aTs_Datetime
	 * @param as_Pattern
	 * @return
	 */
	public static String format(Timestamp aTs_Datetime, String as_Pattern) {
		if (aTs_Datetime == null || as_Pattern == null)
			return null;

		SimpleDateFormat dateFromat = new SimpleDateFormat();
		dateFromat.applyPattern(as_Pattern);

		return dateFromat.format(aTs_Datetime);
	}

	/**
	 * 取得指定日期N天后的日期
	 * 
	 * @param date
	 * @param days
	 * @return
	 */
	public static Date addDays(Date date, int days) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);

		cal.add(Calendar.DAY_OF_MONTH, days);

		return cal.getTime();
	}

	/**
	 * 取得当前日期N天前的日期
	 * 
	 * @param date
	 * @param days
	 * @return
	 */
	public static Date dynamicDays(String days) {
		SimpleDateFormat dateFromat = new SimpleDateFormat("yyyy-MM-dd");
		Date retDate = null;
		try {
			Calendar cal = Calendar.getInstance();
			int date_int = (Integer.parseInt(days));
			if (date_int <= 0)
				return retDate;
			date_int = (date_int * -1) + 1;
			cal.add(Calendar.DAY_OF_YEAR, date_int);
			retDate = dateFromat.parse(dateFromat.format(cal.getTime()));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return retDate;
	}

	/**
	 * 计算两个日期之间相差的天数
	 * 
	 * @param date1
	 * @param date2
	 * @return
	 */
	public static int daysBetween(Date date1, Date date2) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date1);
		long time1 = cal.getTimeInMillis();
		cal.setTime(date2);
		long time2 = cal.getTimeInMillis();
		long between_days = (time2 - time1) / (1000 * 3600 * 24);

		return Integer.parseInt(String.valueOf(between_days));
	}

	/**
	 * 计算两个日期之间相差的时间戳
	 * 
	 * @param date1
	 * @param date2
	 * @return
	 */
	public static long timeInMillisBetween(Date date1, Date date2) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date1);
		long time1 = cal.getTimeInMillis();
		cal.setTime(date2);
		long time2 = cal.getTimeInMillis();
		long between_days = (time2 - time1);
		return between_days;
	}

	/**
	 * 计算当前日期相对于"1977-12-01"的天数
	 * 
	 * @param date
	 * @return
	 */
	public static long getRelativeDays(Date date) {
		Date relativeDate = DateUtil.parseDate("yyyy-MM-dd", "1977-12-01");
		return DateUtil.daysBetween(relativeDate, date);
	}

	public static Date getDateBeforTwelveMonth() {
		String date = "";
		Calendar cla = Calendar.getInstance();
		cla.setTime(getCurrentDate());
		int year = cla.get(Calendar.YEAR) - 1;
		int month = cla.get(Calendar.MONTH) + 1;
		if (month > 9) {
			date = String.valueOf(year) + C_DATE_DIVISION + String.valueOf(month) + C_DATE_DIVISION + "01";
		} else {
			date = String.valueOf(year) + C_DATE_DIVISION + "0" + String.valueOf(month) + C_DATE_DIVISION + "01";
		}

		Date dateBefore = parseDate(date);
		return dateBefore;
	}

	/**
	 * 传入时间字符串,加一天后返回Date
	 * 
	 * @param date
	 *            时间 格式 YYYY-MM-DD
	 * @return
	 */
	public static Date addDate(String date) {
		if (date == null) {
			return null;
		}

		Date tempDate = parseDate(C_DATE_PATTON_DEFAULT, date);
		String year = format(tempDate, "yyyy");
		String month = format(tempDate, "MM");
		String day = format(tempDate, "dd");

		GregorianCalendar calendar = new GregorianCalendar(Integer.parseInt(year), Integer.parseInt(month) - 1, Integer
				.parseInt(day));

		calendar.add(GregorianCalendar.DATE, 1);
		return calendar.getTime();
	}

	/**
	 * 
	 * @param date
	 * @param days
	 * @return
	 */
	public static Date minusDate(String date, int days) {
		if (date == null) {
			return null;
		}
		Date tempDate = parseDate(C_DATE_PATTON_DEFAULT, date);
		String year = format(tempDate, "yyyy");
		String month = format(tempDate, "MM");
		String day = format(tempDate, "dd");
		GregorianCalendar calendar = new GregorianCalendar(Integer.parseInt(year), Integer.parseInt(month) - 1, Integer
				.parseInt(day)
				- days);
		return calendar.getTime();
	}

	/**
	 * 查询条件的开始时间
	 * 
	 * @param startDate
	 * @return
	 */
	public static Date parseBeginDate(String startDate) {
		if (null == startDate || "".equals(startDate.trim())) {
			return null;
		}
		return beginOfTheDay(parseDate(startDate));
	}

	/**
	 * 查询条件的结束时间
	 * 
	 * @param endDate
	 * @return
	 */
	public static Date parseEndDate(String endDate) {
		if (null == endDate || "".equals(endDate.trim())) {
			return null;
		}
		return endOfTheDay(parseDate(endDate));
	}

	/**
	 * 获取今天00点:00分:00秒
	 * 
	 * @return
	 */
	public static Date getTodayZero() {
		return DateUtil.parseDate(DateUtil.getCurrentDateStr("yyyy-MM-dd"));
	}

	/**
	 * 某天的00点:00分:00秒
	 * 
	 * @param date
	 * @return java.util.Date
	 */
	public static Date beginOfTheDay(Date startTime) {
		if (startTime == null)
			return null;
		return DateUtil.parseDate(DateUtil.C_TIME_PATTON_DEFAULT, DateUtil.formatTime(startTime,
				DateUtil.C_TIME_PATTON_DEFAULT).substring(0, 11)
				+ "00:00:00");
	}

	/**
	 * 某天的23点:59分:59秒
	 * 
	 * @param date
	 * @return java.util.Date
	 */
	public static Date endOfTheDay(Date endTime) {
		if (endTime == null)
			return null;
		return DateUtil.parseDate(DateUtil.C_TIME_PATTON_DEFAULT, DateUtil.formatTime(endTime,
				DateUtil.C_TIME_PATTON_DEFAULT).substring(0, 11)
				+ "23:59:59");
	}

	/**
	 * 获取本月第一天的00点:00分:00秒
	 * 
	 * @return java.util.Date
	 */
	public static Date beginOfThisMonth() {
		GregorianCalendar gregorianCalendar = new GregorianCalendar();
		gregorianCalendar.get(Calendar.YEAR);
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
		String startOfMonth = gregorianCalendar.get(Calendar.YEAR) + "-" + (gregorianCalendar.get(Calendar.MONTH) + 1)
				+ "-1";
		try {
			return simpleDateFormat.parse(startOfMonth);
		} catch (ParseException e) {
			loggerService.error("", e);
		}
		return null;
	}

	public static Long getBetweenTime(Long startTime, Long endTime) {
		return (endTime - startTime) / 1000;
	}

	public static Date getNowDateTime(Date now) {
		String nowTimeStr = formatTime(now);
		return parseDateTime(nowTimeStr);
	}

	public static Date getNowDate() {
		String nowTimeStr = getCurrentDateStr(C_DATE_PATTON_DEFAULT);
		return parseDate(nowTimeStr);
	}

	public static Date AddOneDay(String date) {
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		Date middle = parseDate("yyyy-MM-dd", date);
		String tempDate = df.format(middle.getTime() + 1 * 24 * 60 * 60 * 1000);
		return parseDate("yyyy-MM-dd", tempDate);
	}

	/**
	 * 当前日期之前的n天日期 n为整数
	 * 
	 * @param date
	 * @return
	 */
	public static Date AddDay(int n) {
		long nowTime = System.currentTimeMillis();
		long minus = (long)n * 24 * 60 * 60 * 1000;
		return new Date(nowTime - minus);
	}

	public static Date AddOneDay(String format, String date) {
		SimpleDateFormat df = new SimpleDateFormat(format);
		return DateUtil.parseDate(format, df.format(DateUtil.parseDate(format, date).getTime() + 1 * 24 * 60 * 60
				* 1000));
	}

	public static String getXmlTimestamp() {
		SimpleDateFormat sdf = new SimpleDateFormat();
		sdf.applyPattern("yyyyMMddHHmmssSSSS");
		return sdf.format(new Date());

	}

	/**
	 * 获得当月的第一天, 如2009-10-01 00:00:00
	 * 
	 * @param date
	 * @return
	 */
	public static Date getFirstDayOfMonth(Date date) {
		GregorianCalendar gc = new GregorianCalendar();
		gc.setTime(date);
		gc.set(Calendar.DAY_OF_MONTH, gc.getActualMinimum(Calendar.DAY_OF_MONTH));
		gc.set(Calendar.HOUR_OF_DAY, gc.getActualMinimum(Calendar.HOUR_OF_DAY));
		gc.set(Calendar.MINUTE, gc.getActualMinimum(Calendar.MINUTE));
		gc.set(Calendar.SECOND, gc.getActualMinimum(Calendar.SECOND));
		return gc.getTime();
	}

	/**
	 * 获得当月的最后一天, 如2009-10-30 23:59:59
	 * 
	 * @param date
	 * @return
	 */
	public static Date getLastDayOfMonth(Date date) {
		GregorianCalendar gc = new GregorianCalendar();
		gc.setTime(date);
		gc.set(Calendar.DAY_OF_MONTH, gc.getActualMaximum(Calendar.DAY_OF_MONTH));
		gc.set(Calendar.HOUR_OF_DAY, gc.getActualMaximum(Calendar.HOUR_OF_DAY));
		gc.set(Calendar.MINUTE, gc.getActualMaximum(Calendar.MINUTE));
		gc.set(Calendar.SECOND, gc.getActualMaximum(Calendar.SECOND));
		return gc.getTime();
	}

	/**
	 * 获取某周第一天日期 00点:00分:00秒
	 * 
	 * @param date
	 *            这周中的一天
	 * @param start
	 *            1--第一天是周日， 2--第一天是周一， 类推
	 * @return
	 */
	public static Date getFirstDayOfWeek(Date date, int start) {
		GregorianCalendar cal = new GregorianCalendar();
		cal.setTime(date);
		int day_of_week = cal.get(Calendar.DAY_OF_WEEK) - start;
		cal.add(Calendar.DATE, -day_of_week);

		cal.set(Calendar.HOUR_OF_DAY, cal.getActualMinimum(Calendar.HOUR_OF_DAY));
		cal.set(Calendar.MINUTE, cal.getActualMinimum(Calendar.MINUTE));
		cal.set(Calendar.SECOND, cal.getActualMinimum(Calendar.SECOND));
		return cal.getTime();
	}

	/**
	 * 获取某周最后一天日期 23:59:59
	 * 
	 * @param date
	 *            这周中的一天
	 * @param start
	 *            start 1--第一天是周日， 2--第一天是周一， 类推
	 * @return
	 */
	public static Date getLastDayOfWeek(Date date, int start) {
		GregorianCalendar cal = new GregorianCalendar();
		cal.setTime(date);
		int day_of_week = cal.get(Calendar.DAY_OF_WEEK) - start;
		cal.add(Calendar.DATE, -day_of_week); // 获得第一天
		cal.add(Calendar.DATE, 6); // +6天 就得到最后一天

		cal.set(Calendar.HOUR_OF_DAY, cal.getActualMaximum(Calendar.HOUR_OF_DAY));
		cal.set(Calendar.MINUTE, cal.getActualMaximum(Calendar.MINUTE));
		cal.set(Calendar.SECOND, cal.getActualMaximum(Calendar.SECOND));
		return cal.getTime();
	}

	/**
	 * 获取某个日期mins分钟后的日期
	 * 
	 * @param date
	 * @param mins
	 * @return
	 */
	public static Date getAfterNMinute(Date date, int mins) {
		GregorianCalendar cal = new GregorianCalendar();
		cal.setTime(date);
		cal.add(Calendar.MINUTE, mins);
		return cal.getTime();

	}

	/**
	 * 获取指定日期的下一个星期
	 * 
	 * @param date
	 * @return
	 */
	public static Date getNextWeek(Date date) {
		GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		gc.add(Calendar.DATE, 7);

		return gc.getTime();
	}

	/**
	 * 获取指定日期的下几个月
	 * 
	 * @param date
	 *            指定日期
	 * @param num
	 *            月数
	 * @return
	 */
	public static Date getNextMonth(Date date, int num) {
		GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
		gc.setTime(date);
		gc.add(Calendar.MONTH, num);
		gc.getTime();
		return gc.getTime();
	}

	/**
	 * 比较两个时间大少
	 * 
	 * @param date1
	 * @param date2
	 * @return
	 */
	public static boolean compareDate(Date date1, Date date2) {
		if (date1.getTime() < date2.getTime()) {
			return true;
		} else {
			return false;
		}
	}

	public static Date parseTime(String strFormat, String dateValue) {
		if (dateValue == null || "".equals(dateValue))
			return null;
		SimpleDateFormat dateFormat = null;

		if (strFormat == null) {
			strFormat = C_TIME_PATTON_DEFAULT;
			dateFormat = new SimpleDateFormat(strFormat);
		} else if (strFormat.indexOf("EEE") == -1) {
			dateFormat = new SimpleDateFormat(strFormat);
		} else if (strFormat.indexOf("星期") > -1)
			dateFormat = new SimpleDateFormat(strFormat, Locale.CHINESE);
		else {
			dateFormat = new SimpleDateFormat(strFormat, Locale.ENGLISH);
		}

		Date newDate = null;

		try {
			newDate = dateFormat.parse(dateValue);
		} catch (ParseException pe) {
			loggerService.error("", pe);
			newDate = null;
		}

		return newDate;
	}
}
